home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2001 December / pcwk12201b.iso / Wersje pelne i specjalne / Winamp 2.77 i 3.0beta / wasabi-sdk_beta1.exe / studio / common / buttwnd.cpp < prev    next >
C/C++ Source or Header  |  2001-10-08  |  14KB  |  559 lines

  1. /*
  2.  
  3.   Nullsoft WASABI Source File License
  4.  
  5.   Copyright 1999-2001 Nullsoft, Inc.
  6.  
  7.     This software is provided 'as-is', without any express or implied
  8.     warranty.  In no event will the authors be held liable for any damages
  9.     arising from the use of this software.
  10.  
  11.     Permission is granted to anyone to use this software for any purpose,
  12.     including commercial applications, and to alter it and redistribute it
  13.     freely, subject to the following restrictions:
  14.  
  15.     1. The origin of this software must not be misrepresented; you must not
  16.        claim that you wrote the original software. If you use this software
  17.        in a product, an acknowledgment in the product documentation would be
  18.        appreciated but is not required.
  19.     2. Altered source versions must be plainly marked as such, and must not be
  20.        misrepresented as being the original software.
  21.     3. This notice may not be removed or altered from any source distribution.
  22.  
  23.  
  24.   Brennan Underwood
  25.   brennan@nullsoft.com
  26.  
  27. */
  28.  
  29. // bitmap-style buttons
  30.  
  31. #include "canvas.h"
  32. #include "buttwnd.h"
  33. #include "std.h"
  34. #include "region.h"
  35. #include "notifmsg.h"
  36.  
  37. #include "../studio/api.h"
  38. #include "../studio/paintsets.h"
  39.  
  40. #define DEFAULT_BUTTON_HEIGHT 20
  41.  
  42. ButtonWnd::ButtonWnd() {
  43.   currgn = NULL;
  44.   hirgn = NULL;
  45.   normalrgn = NULL;
  46.   pushedrgn = NULL;
  47.     activatedrgn = NULL;
  48.   base_texture = NULL;
  49.   xShift=0;
  50.   yShift=0;
  51.   textsize = DEFAULT_BUTTON_TEXT_SIZE;
  52.   buttonid = 0;
  53.   textjustify = BUTTONJUSTIFY_CENTER;
  54.   activated = 0;
  55.   folderstyle = 0;
  56.   userhilite = 0;
  57.   userdown = 0;
  58.   use_base_texture = 0;
  59.   center_bitmap = 0;
  60.   enabled = 1;
  61.   checked=0;
  62.   autodim=0;
  63.   borders = 1;
  64.   iwantfocus = 1;
  65.   color_text = "studio.button.text";
  66.   color_hilite = "studio.button.hiliteText";
  67.   color_dimmed = "studio.button.dimmedText";         
  68.   checkbmp = "studio.button.checkmark";  
  69.   alpha = 255;
  70.   inactivealpha = 255;
  71.   activealpha = 255;
  72.   rectrgn=0;
  73.   hilited=0;
  74. }
  75.  
  76. ButtonWnd::~ButtonWnd() {
  77.   delete normalrgn;
  78.   delete pushedrgn;
  79.   delete hirgn;
  80.   delete activatedrgn;
  81. }
  82.  
  83. void ButtonWnd::setRectRgn(int r) {
  84.   rectrgn = r;
  85. }
  86.  
  87. int ButtonWnd::onMouseMove(int x, int y) {
  88.   hilited=0;
  89.  
  90.   if (getDown() && pushedrgn) 
  91.     currgn = pushedrgn;
  92.   else {
  93.     Region *old = currgn;
  94.     if (hirgn) 
  95.       currgn = hirgn;
  96.     else
  97.       currgn = NULL;
  98.     if (mouseInRegion(x, y))
  99.       hilited=1;
  100.     else
  101.       currgn = normalrgn;
  102.     }
  103.  
  104.   return BUTTONWND_PARENT::onMouseMove(x, y);
  105. }
  106. void ButtonWnd::onLeaveArea() {
  107.   hilited=0;
  108.   if (hirgn) invalidate();
  109. }
  110.  
  111. BOOL ButtonWnd::mouseInRegion(int x, int y) {
  112.   POINT pos={x,y};
  113.   POINT p2=pos;
  114.  
  115.   RECT r;
  116.   getClientRect(&r);
  117.   pos.x-=r.left;
  118.   pos.y-=r.top;
  119.   if (((!currgn || rectrgn) && PtInRect(&r, p2)) || (currgn && currgn->ptInRegion(&pos)))
  120.     return TRUE;
  121.   return FALSE;
  122. }
  123.  
  124. int ButtonWnd::setBitmaps(const char *_normal, const char *_pushed, const char *_hilited, const char *_activated) {
  125.  
  126.   if (_normal) { delete normalrgn; normalrgn = NULL; }
  127.   if (_pushed) { delete pushedrgn; pushedrgn = NULL; }
  128.   if (_hilited) { delete hirgn; hirgn = NULL; }
  129.     if (_activated) { delete activatedrgn; activatedrgn = NULL; }
  130.  
  131.   if (_normal) {
  132.     normalbmp = _normal;
  133.     normalrgn = new Region(normalbmp.getBitmap(), 0, 0);
  134.   }
  135.  
  136.   if (_pushed) {
  137.     pushedbmp = _pushed;
  138.     pushedrgn = new Region(pushedbmp.getBitmap(), 0, 0);
  139.   }
  140.  
  141.   if (_hilited) {
  142.     hilitebmp = _hilited;
  143.     hirgn = new Region(hilitebmp.getBitmap(), 0, 0);
  144.   }
  145.  
  146.   if (_activated) {
  147.     activatedbmp = _activated;
  148.     activatedrgn = new Region(activatedbmp.getBitmap(), 0, 0);
  149.   }
  150.  
  151.  
  152.   return 1;
  153. }
  154.  
  155. void ButtonWnd::freeResources() {
  156.   BUTTONWND_PARENT::freeResources();
  157.   delete normalrgn;
  158.   delete pushedrgn;
  159.   delete hirgn;
  160.   delete activatedrgn;
  161.   pushedrgn=NULL;
  162.   normalrgn=NULL;
  163.   hirgn=NULL;
  164.   activatedrgn=NULL;
  165.   currgn=NULL;
  166. }
  167.  
  168. void ButtonWnd::reloadResources() {
  169.   BUTTONWND_PARENT::reloadResources();
  170.   if (normalbmp.getBitmap())
  171.     normalrgn = new Region(normalbmp.getBitmap(), 0, 0);
  172.   if (pushedbmp.getBitmap())
  173.     pushedrgn = new Region(pushedbmp.getBitmap(), 0, 0);
  174.   if (hilitebmp.getBitmap())
  175.     hirgn = new Region(hilitebmp.getBitmap(), 0, 0);
  176.   if (activatedbmp.getBitmap())
  177.     activatedrgn = new Region(activatedbmp.getBitmap(), 0, 0);
  178. }
  179.  
  180. int ButtonWnd::setBitmapCenter(int centerit) {
  181.   return center_bitmap = !!centerit;
  182. }
  183.  
  184. int ButtonWnd::setBitmaps(HINSTANCE hInst, int _normal, int _pushed, int _hilited, int _activated){
  185.   if (_normal) { delete normalrgn; normalrgn = NULL; }
  186.   if (_pushed) { delete pushedrgn; pushedrgn = NULL; }
  187.   if (_hilited) { delete hirgn; hirgn = NULL; }
  188.     if (_activated) { delete activatedrgn; activatedrgn = NULL; }
  189.  
  190.   if (_normal) {
  191.     normalbmp.setHInstance(hInst);
  192.     normalbmp = _normal;
  193.     normalrgn = new Region(normalbmp.getBitmap(), 0, 0);
  194.   }
  195.  
  196.   if (_pushed) {
  197.     pushedbmp.setHInstance(hInst);
  198.     pushedbmp = _pushed;
  199.     pushedrgn = new Region(pushedbmp.getBitmap(), 0, 0);
  200.   }
  201.  
  202.   if (_hilited) {
  203.     hilitebmp.setHInstance(hInst);
  204.     hilitebmp = _hilited;
  205.     hirgn = new Region(hilitebmp.getBitmap(), 0, 0);
  206.   }
  207.  
  208.   if (_activated) {
  209.     activatedbmp.setHInstance(hInst);
  210.     activatedbmp = _activated;
  211.     activatedrgn = new Region(activatedbmp.getBitmap(), 0, 0);
  212.   }
  213.  
  214.   return 1;
  215. }
  216.  
  217. void ButtonWnd::setUseBaseTexture(int useit) {
  218.   use_base_texture = useit;
  219.   invalidate();
  220. }
  221.  
  222. void ButtonWnd::setBaseTexture(SkinBitmap *bmp, int x, int y, int tile) {
  223.   base_texture = bmp;
  224.   use_base_texture = TRUE;
  225.   tile_base_texture=tile;
  226.   xShift=x;
  227.   yShift=y;
  228.   invalidate();
  229. }
  230.  
  231. int ButtonWnd::setButtonText(const char *text, int size) {
  232.   textsize = size;
  233.   ASSERT(textsize > 0);
  234.   setName(text);
  235.   invalidate();
  236.   return 1;
  237. }
  238.  
  239. void ButtonWnd::setTextJustification(ButtonJustify jus) {
  240.   textjustify = jus;
  241.   invalidate();
  242. }
  243.  
  244. int ButtonWnd::getWidth() {
  245.   int addl=0;
  246.   if (checked) {
  247.     addl=checkbmp.getWidth()+3;
  248.   }
  249.   if (rightbmp.getBitmap())
  250.     addl+=rightbmp.getWidth()+3;
  251.   if (normalbmp == NULL) {
  252.     BltCanvas blt(10,10);
  253.     blt.pushTextSize(textsize);
  254.     char *lstr=(char*)MALLOC(STRLEN(getName())+4);
  255.     STRCPY(lstr,getName());
  256.     if (STRSTR(lstr,"\t")) STRCAT(lstr,"   ");
  257.     int a=max((blt.getTextWidth(lstr)*11)/10,8)+addl;
  258.     FREE(lstr);
  259.     blt.popTextSize();
  260.     return a;
  261.   }
  262.   return normalbmp.getWidth()+addl;
  263. }
  264.  
  265. int ButtonWnd::getHeight() {
  266.   int minh=0;
  267.   if (checked>0)
  268.     minh=checkbmp.getHeight();
  269.   if (rightbmp.getBitmap())
  270.     minh=max(rightbmp.getHeight(),minh);
  271.   if (normalbmp == NULL) {
  272.     BltCanvas blt(10,10);
  273.     blt.pushTextSize(textsize);
  274.     int r = max(max((blt.getTextHeight(getName())*11)/10,minh),4);
  275.     blt.popTextSize();
  276.     return r;
  277.   }
  278.   return max(normalbmp.getHeight(),minh);
  279. }
  280.  
  281. void ButtonWnd::enableButton(int _enabled) {
  282.   _enabled = !!_enabled;
  283.   if (enabled != _enabled) invalidate();
  284.   enabled = _enabled;
  285.   onEnable(enabled);
  286. }
  287.  
  288. int ButtonWnd::getEnabled() const {
  289.   return enabled;
  290. }
  291.  
  292. int ButtonWnd::onPaint(Canvas *canvas) {
  293.   PaintBltCanvas paintcanvas;
  294.   SkinBitmap *bmp;
  295.   RECT r;
  296.   int labelxoffs=0;
  297.  
  298.   if (checked) labelxoffs+=3+checkbmp.getWidth();
  299.  
  300.   if (canvas == NULL) {
  301.     if (!paintcanvas.beginPaint(this)) return 0;
  302.     canvas = &paintcanvas;
  303.   }
  304.   BUTTONWND_PARENT::onPaint(canvas);
  305.  
  306.   bmp = normalbmp;
  307.   if (pushedbmp && (getDown() || userdown)) bmp = pushedbmp;
  308.   else if ((getHilite() || userhilite) && hilitebmp) bmp = hilitebmp;
  309.   else if (activatedbmp && activated) bmp = activatedbmp;
  310.  
  311.   getClientRect(&r);
  312.   int set = (userdown||getDown()) ? Paintset::BUTTONDOWN : Paintset::BUTTONUP;
  313.   if (!enabled) set=Paintset::BUTTONDISABLED;
  314.  
  315.   RECT nr = r;
  316. //  RECT fcr = r;
  317.   if (use_base_texture) {
  318.     if (!base_texture)
  319.       renderBaseTexture(canvas, r);
  320.     else {
  321.       RECT cr;
  322.       cr.left = xShift;
  323.       cr.top = yShift;
  324.       cr.right = cr.left + (r.right-r.left);
  325.       cr.bottom = cr.top + (r.bottom-r.top);
  326.       if (tile_base_texture) base_texture->blitTile(canvas, &r,xShift,yShift);
  327.       else base_texture->stretchToRectAlpha(canvas, &cr, &r, alpha);
  328.     }
  329.   } else {
  330.     if (folderstyle) nr.bottom += 3;
  331.     if (borders) api->paintset_render(set, canvas, &nr, alpha);
  332.   }
  333.  
  334.   if (checked>0) {
  335.     RECT ar;
  336.     int c=(r.top+r.bottom)/2;
  337.     ar.left=r.left;
  338.     ar.top=c-checkbmp.getHeight()/2;
  339.     ar.bottom=ar.top+checkbmp.getHeight();
  340.     ar.right=r.left+checkbmp.getWidth();
  341.     checkbmp.getBitmap()->stretchToRectAlpha(canvas,&ar,alpha);
  342.   }
  343.   if (rightbmp.getBitmap()) {
  344.     RECT ar;
  345.     int c=(r.top+r.bottom)/2;
  346.     ar.top=c-rightbmp.getHeight()/2;
  347.     ar.bottom=ar.top+rightbmp.getHeight();
  348.     ar.right=r.right;
  349.     ar.left=ar.right-rightbmp.getWidth();
  350.     
  351.     rightbmp.getBitmap()->stretchToRectAlpha(canvas,&ar,alpha);
  352.   }
  353.   
  354.   if (bmp != NULL) {
  355.     RECT br = r;
  356.     if (center_bitmap) {
  357.       int w = (r.right - r.left) - getWidth() - labelxoffs;
  358.       int h = (r.bottom - r.top) - getHeight();
  359.       br.top = r.top + h/2;
  360.       br.bottom = br.top + getHeight();
  361.       br.left = r.left + w/2 + labelxoffs;
  362.       br.right = br.left + getWidth() - (rightbmp.getBitmap()?rightbmp.getWidth()+3:0);
  363.     } else {
  364.       br.left += labelxoffs;
  365.       br.right -= (rightbmp.getBitmap()?rightbmp.getWidth()+3:0);
  366.     }
  367.     int alpha2;
  368.     if (!hilitebmp && enabled && autodim) {
  369.       alpha2=128;
  370.       if (getHilite() || userhilite) alpha2=255;
  371.     } else alpha2 = enabled ? 255 : 64;
  372.     bmp->stretchToRectAlpha(canvas, &br,autodim ? (alpha+alpha2)>>1 : alpha);
  373.   }
  374.  
  375.   if (getName() != NULL) {
  376.     int offset = (enabled&&(userdown||getDown())) ? 1 : 0;
  377.     canvas->setTextOpaque(FALSE);
  378.     //canvas->setTextVariable(TRUE); //FGTEMP!
  379.     canvas->pushTextSize(textsize);
  380.     if (!enabled)
  381.       canvas->setTextColor(color_dimmed);
  382.     else if (userhilite)
  383.       canvas->setTextColor(color_hilite);
  384.     else
  385.       canvas->setTextColor(color_text);
  386.     int h=(r.bottom-r.top-canvas->getTextHeight(getName()))/2;
  387.     if (h<0) h=0;
  388.  
  389.     r.left += offset + labelxoffs;
  390.     r.right += offset - (rightbmp.getBitmap()?rightbmp.getWidth()+3:0);
  391.     r.top += offset+h;
  392.     r.bottom = r.top+canvas->getTextHeight(getName());
  393.  
  394.     if (textjustify == BUTTONJUSTIFY_CENTER)
  395.       canvas->textOutCentered(&r, getName());
  396.     else if (textjustify == BUTTONJUSTIFY_LEFT)
  397.     {
  398.       if (!STRSTR(getName(),"\t"))
  399.         canvas->textOutEllipsed(r.left, r.top, r.right-r.left, r.bottom-r.top, getName());
  400.       else
  401.       {
  402.         char *lstr=STRDUP(getName());
  403.         char *p=STRSTR(lstr,"\t");
  404.         if (p) *p++=0;
  405.         else p="";
  406.         int tw=canvas->getTextWidth(p);
  407.         canvas->textOutEllipsed(r.left, r.top, r.right-r.left-tw, r.bottom-r.top, lstr);
  408.         canvas->textOutEllipsed(r.right-tw, r.top, tw, r.bottom-r.top, p);
  409.         FREE(lstr);
  410.       }
  411.     }
  412.  
  413.     canvas->popTextSize();
  414.   }
  415.  
  416.  
  417. /*  if (enabled && gotFocus() && wantFocus()) { // SKIN ME
  418.     fcr.left+=3;
  419.     fcr.right-=3;
  420.     fcr.top+=3;
  421.     fcr.bottom-=3;
  422.     DrawFocusRect(canvas->getHDC(), &fcr);
  423.   }*/
  424.  
  425.   return 1;
  426. }
  427.  
  428. int ButtonWnd::onChar(char c) {
  429.   if (c == 13) {
  430.   
  431.   } else return BUTTONWND_PARENT::onChar(c);
  432.   return 1;
  433. }
  434.  
  435. void ButtonWnd::onLeftPush(int x, int y) {
  436.   notifyParent(CHILD_NOTIFY_LEFTPUSH, buttonid);
  437. }
  438. void ButtonWnd::onRightPush(int x, int y) {
  439.   notifyParent(CHILD_NOTIFY_RIGHTPUSH, buttonid);
  440. }
  441. void ButtonWnd::onLeftDoubleClick(int x, int y) {
  442.   notifyParent(CHILD_NOTIFY_LEFTDOUBLECLICK, buttonid);
  443. }
  444. void ButtonWnd::onRightDoubleClick(int x, int y) {
  445.   notifyParent(CHILD_NOTIFY_RIGHTDOUBLECLICK, buttonid);
  446. }
  447.  
  448. void ButtonWnd::setHilite(int h) {
  449.   h = !!h;
  450.   if (userhilite != h) {
  451.     userhilite = h;
  452.     invalidate();
  453.   }
  454. }
  455.  
  456. int ButtonWnd::getHilite() {
  457.   return userhilite || hilited;
  458. }
  459.  
  460. int ButtonWnd::getPushed() const {
  461.   return userdown;
  462. }
  463.  
  464. void ButtonWnd::setPushed(int p) {
  465.   p = !!p;
  466.   if (userdown != p)
  467.   {
  468.     userdown=p;
  469.     invalidate();
  470.   }
  471. }
  472.  
  473. int ButtonWnd::onResize() {
  474. invalidate();
  475. return 1;
  476. }
  477.  
  478. void ButtonWnd::setCheckBitmap(char *checkbm) {
  479.   checkbmp = checkbm;
  480. }
  481.  
  482. int ButtonWnd::setRightBitmap(char *bitmap) {
  483.   rightbmp=bitmap;
  484.   return 1;
  485. }
  486.  
  487. void ButtonWnd::setActivatedButton(int a) {
  488.   if (activated != a) {
  489.     activated = a;
  490.     invalidate();
  491.     onActivateButton(activated);
  492.   }
  493. }
  494.  
  495. int ButtonWnd::onActivateButton(int active) {
  496.   return 1;
  497. }
  498.  
  499. int ButtonWnd::getActivatedButton() const {
  500.   return activated;
  501. }
  502.  
  503. int ButtonWnd::onGetFocus() {
  504.   BUTTONWND_PARENT::onGetFocus();
  505. //  invalidate();
  506.   return 1;
  507. }
  508.  
  509. int ButtonWnd::onKillFocus() {
  510.   BUTTONWND_PARENT::onKillFocus();
  511. //  invalidate();
  512.   return 1;
  513. }
  514.  
  515. void ButtonWnd::setColors(const char *text, const char *hilite, const char *dimmed) {
  516.   color_text=text;
  517.   color_hilite=hilite;
  518.   color_dimmed=dimmed;
  519. }
  520.  
  521. int ButtonWnd::onEnable(int is) {
  522.   return BUTTONWND_PARENT::onEnable(is);
  523. }
  524.  
  525. void ButtonWnd::setAlpha(int a) {
  526.   if (a != alpha) {
  527.     alpha = a;
  528.     invalidate();
  529.   }
  530. }
  531.  
  532. int ButtonWnd::getAlpha(void) const {
  533.   return alpha;
  534. }
  535.  
  536. int ButtonWnd::onActivate() {
  537.   if (activealpha != alpha) {
  538.     alpha = activealpha;
  539.     invalidate();
  540.   }
  541.   return 0;
  542. }
  543.  
  544. int ButtonWnd::onDeactivate() {
  545.   if (inactivealpha != alpha) {
  546.     alpha = inactivealpha;
  547.     invalidate();
  548.   }
  549.   return 0;
  550. }
  551.  
  552. int ButtonWnd::getPreferences(int what) {
  553.   switch (what) {
  554.     case SUGGESTED_W: return normalbmp.getWidth();
  555.     case SUGGESTED_H: return normalbmp.getHeight();
  556.   }
  557.   return BUTTONWND_PARENT::getPreferences(what);
  558. }
  559.